package com.example.waterdispenserm2.mo.usbmain;






import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;

import com.example.waterdispenserm2.util.MyLog;
import com.google.gson.Gson;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.hoho.android.usbserial.util.SerialInputOutputManager;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class UsbMainInductionCookerController {
    private Context context;
    private UsbSerialPort port;
    private SerialInputOutputManager serialIoManager;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private ControllerCallback callback;
    private UsbDeviceConnection connection;
    private boolean isConnected = false;
    private ScheduledFuture<?> scheduledTask;

    // 当前显示状态
    private int thousands = 0;
    private int hundreds = 0;
    private int tens = 0;
    private int units = 0;
    private byte ledStatus = 0;

    // 最后接收到的按键
    private int lastKeyCode = 0;

    // 段码表 (0-9, A-F)
    public static final byte[] SEGMENT_CODES = {
            (byte) 0x3F, // 0: 00111111
            (byte) 0x06, // 1: 00000110
            (byte) 0x5B, // 2: 01011011
            (byte) 0x4F, // 3: 01001111
            (byte) 0x66, // 4: 01100110
            (byte) 0x6D, // 5: 01101101
            (byte) 0x7D, // 6: 01111101
            (byte) 0x07, // 7: 00000111
            (byte) 0x7F, // 8: 01111111
            (byte) 0x6F, // 9: 01101111
            (byte) 0x77, // A: 01110111
            (byte) 0x7C, // B: 01111100
            (byte) 0x39, // C: 00111001
            (byte) 0x5E, // D: 01011110
            (byte) 0x79, // E: 01111001
            (byte) 0x71  // F: 01110001
    };

    // LED状态定义
    public static final byte LED_FRYING = (byte) 0x80;     // 炒菜  10000000
    public static final byte LED_PORRIDGE = (byte) 0x40;   // 煲粥  01000000
    public static final byte LED_HOTPOT = (byte) 0x20;     // 火锅  00100000
    public static final byte LED_HIGH_FIRE = (byte) 0x10;  // 武火  00010000
    public static final byte LED_LOW_FIRE = (byte) 0x08;   // 文火  00001000
    public static final byte LED_BOIL_WATER = (byte) 0x04; // 烧水  00000100
    public static final byte LED_STEAM = (byte) 0x02;      // 蒸煮  00000010
    public static final byte LED_STEW = (byte) 0x01;       // 煲汤  00000001

    // 按键定义
    public static final int KEY_NONE = 0;
    public static final int KEY_POWER = 1;
    public static final int KEY_TIMER = 2;
    public static final int KEY_DECREASE = 3;
    public static final int KEY_INCREASE = 4;
    public static final int KEY_FUNCTION = 5;
    public static final int KEY_START = 6;

    public interface ControllerCallback {
        void onConnectionStatusChanged(boolean connected);
        void onError(String errorMessage);
        void onKeyReceived(int keyCode);
        void onDataReceived(byte[] data);
        void onDataSent(byte[] data);
    }

    public UsbMainInductionCookerController(Context context, ControllerCallback callback) {
        this.context = context;
        this.callback = callback;
    }

    public boolean connectToDevice() {
        // 查找USB设备
        UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);

        if (availableDrivers.isEmpty()) {
            callback.onError("未找到USB转1-Wire适配器");
            return false;
        }

        // 获取第一个可用设备
        UsbSerialDriver driver = availableDrivers.get(0);
        UsbDevice device = driver.getDevice();
        if (!usbManager.hasPermission(device)) {
            callback.onError("无USB设备权限");
            return false;
        }

        try {
            // 打开连接
            connection = usbManager.openDevice(device);
            if (connection == null) {
                callback.onError("无法打开USB连接");
                return false;
            }

            port = driver.getPorts().get(0);
            port.open(connection);
            port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

            // 启动数据监听
            serialIoManager = new SerialInputOutputManager(port, new SerialInputOutputManager.Listener() {
                @Override
                public void onNewData(byte[] data) {
                    callback.onDataReceived(data);
                    processReceivedData(data);
                }

                @Override
                public void onRunError(Exception e) {
                    callback.onError("通信错误: " + e.getMessage());
                }
            });
            executor.submit(serialIoManager);

            // 启动定时发送任务
            startScheduledSending();

            isConnected = true;
            callback.onConnectionStatusChanged(true);
            return true;
        } catch (IOException e) {
            callback.onError("连接失败: " + e.getMessage());
            return false;
        }
    }

    private void startScheduledSending() {
        // 每隔100ms发送一次数据
        if (scheduledTask != null && !scheduledTask.isCancelled()) {
            scheduledTask.cancel(true);
        }

        scheduledTask = scheduler.scheduleAtFixedRate(() -> {
            if (isConnected && port != null) {
                sendDisplayData();
            }
        }, 0, 100, TimeUnit.MILLISECONDS);
    }

    public void disconnect() {
        // 停止定时任务
        if (scheduledTask != null) {
            scheduledTask.cancel(true);
            scheduledTask = null;
        }

        if (serialIoManager != null) {
            serialIoManager.stop();
            serialIoManager = null;
        }
        if (port != null) {
            try {
                port.close();
            } catch (IOException e) {
                // 忽略关闭错误
            }
            port = null;
        }
        if (connection != null) {
            connection.close();
            connection = null;
        }
        isConnected = false;
        callback.onConnectionStatusChanged(false);
    }

    public void setDisplayData(int thousands, int hundreds, int tens, int units, byte ledStatus) {
        this.thousands = thousands;
        this.hundreds = hundreds;
        this.tens = tens;
        this.units = units;
        this.ledStatus = ledStatus;
    }

    private void sendDisplayData() {
        try {
            // 构建数据包：引导码 + 识别码(0xA5) + 5字节显示码 + 校验码
            byte[] packet = new byte[7];

            // 识别码
            packet[0] = (byte) 0xA5;

            // 显示码
            packet[1] = SEGMENT_CODES[thousands]; // 千位
            packet[2] = SEGMENT_CODES[hundreds];  // 百位
            packet[3] = SEGMENT_CODES[tens];      // 十位
            packet[4] = SEGMENT_CODES[units];     // 个位
            packet[5] = ledStatus;                // LED状态

            // 计算校验码 (所有字节和的低8位)
            int checksum = 0;
            for (int i = 0; i < 6; i++) {
                checksum += packet[i] & 0xFF;
            }
            packet[6] = (byte) (checksum & 0xFF);

            MyLog.d("---发送--",new Gson().toJson(packet));
            // 发送数据
            port.write(packet, 100);
            callback.onDataSent(packet);
        } catch (IOException e) {
            callback.onError("发送失败: " + e.getMessage());
        }
    }

    private void processReceivedData(byte[] data) {
        // 从机回复协议帧：1byte数据码 + 1byte校验码 (2字节)
        if (data.length < 2) {
            callback.onError("无效的回复长度: " + data.length + "字节");
            return;
        }

        byte keyCode = data[0];
        byte checksum = data[1];

        // 验证校验码 (数据码取反)
        if ((byte) (~keyCode) != checksum) {
            callback.onError("按键校验失败: 计算值0x" +
                    String.format("%02X", (byte) ~keyCode) +
                    " 接收值0x" + String.format("%02X", checksum));
            return;
        }

        // 保存并回调按键值
        lastKeyCode = keyCode & 0xFF;
        callback.onKeyReceived(lastKeyCode);
    }

    public static String getKeyName(int keyCode) {
        switch (keyCode) {
            case KEY_POWER: return "电量/电压";
            case KEY_TIMER: return "定时/预约";
            case KEY_DECREASE: return "减";
            case KEY_INCREASE: return "加";
            case KEY_FUNCTION: return "功能";
            case KEY_START: return "启动";
            default: return "无按键";
        }
    }

    public static String getSegmentName(byte segment) {
        for (int i = 0; i < SEGMENT_CODES.length; i++) {
            if (SEGMENT_CODES[i] == segment) {
                return String.valueOf(i < 10 ? i : (char)('A' + i - 10));
            }
        }
        return "?";
    }

    public static String byteToBinaryString(byte b) {
        return String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
    }

}
